// Package config 提供应用程序配置管理功能
// 该包使用Viper库来加载和管理YAML格式的配置文件
package config

import (
	"log"
	"os"
	"path/filepath"

	"github.com/spf13/viper"
)

// Config 应用程序配置结构体，包含所有配置项
type Config struct {
	// Server 服务器配置
	Server ServerConfig `mapstructure:"server"`
	// Database 数据库配置
	Database DatabaseConfig `mapstructure:"database"`
	// JWT JWT认证配置
	JWT JWTConfig `mapstructure:"jwt"`
}

// ServerConfig 服务器配置结构体
type ServerConfig struct {
	// Port 服务器监听端口，格式为":8080"
	Port string `mapstructure:"port"`
}

// DatabaseConfig 数据库配置结构体
type DatabaseConfig struct {
	// URL 数据库连接URL
	URL string `mapstructure:"url"`
}

// JWTConfig JWT配置结构体
type JWTConfig struct {
	// Secret JWT签名密钥
	Secret string `mapstructure:"secret"`
	// Expiration JWT过期时间（小时）
	Expiration int `mapstructure:"expiration"`
}

// LoadConfig 从config.yaml文件加载配置
// 返回值: *Config - 配置结构体指针
func LoadConfig() *Config {
	// 设置默认配置文件名和类型
	viper.SetConfigName("config")
	viper.SetConfigType("yaml")

	// 设置配置文件搜索路径
	// 添加当前工作目录
	viper.AddConfigPath(".")
	// 添加上上级目录（用于调试加载根目录下的配置文件）
	viper.AddConfigPath("../..")

	// 添加项目根目录的绝对路径
	if rootDir, err := filepath.Abs("."); err == nil {
		viper.AddConfigPath(rootDir)
	}

	// 添加bin目录（用于构建后的程序）
	viper.AddConfigPath("./bin")

	// 设置默认值
	viper.SetDefault("server.port", ":8080")
	viper.SetDefault("database.url", "postgres://postgres:postgres@localhost:5432/aigen_todo?sslmode=disable")
	viper.SetDefault("jwt.secret", "default_jwt_secret")
	viper.SetDefault("jwt.expiration", 24)

	// 尝试读取配置文件
	if err := viper.ReadInConfig(); err != nil {
		if _, ok := err.(viper.ConfigFileNotFoundError); ok {
			log.Println("Config file not found, using default values")
		} else {
			log.Printf("Error reading config file: %v", err)
		}
	} else {
		log.Printf("Using config file: %s", viper.ConfigFileUsed())
	}

	// 将配置绑定到结构体
	var config Config
	if err := viper.Unmarshal(&config); err != nil {
		log.Fatalf("Unable to decode into struct: %v", err)
	}

	// 检查环境变量覆盖
	if port := os.Getenv("PORT"); port != "" {
		config.Server.Port = port
	}
	if dbURL := os.Getenv("DATABASE_URL"); dbURL != "" {
		config.Database.URL = dbURL
	}
	if jwtSecret := os.Getenv("JWT_SECRET"); jwtSecret != "" {
		config.JWT.Secret = jwtSecret
	}

	return &config
}
